package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.component.WeaTableColumnGroup;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.progress.ProgressDTO;
import com.engine.salary.entity.salaryacct.dto.ConsolidatedTaxDetailDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultDetailDTO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctResultListColumnDTO;
import com.engine.salary.entity.salaryacct.param.*;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.valid.ValidUtil;
import com.engine.salary.wrapper.proxy.SalaryAcctResultWrapperProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.hrm.User;

import java.math.BigDecimal;
import java.util.*;

/**
 * 薪资核算结果
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
@Slf4j
public class SalaryAcctResultWrapper extends Service implements SalaryAcctResultWrapperProxy {

    private SalaryAcctResultService getSalaryAcctResultService(User user) {
        return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
    }

    private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
        return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private SalarySobItemService getSalarySobItemService(User user) {
        return ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
    }

    private SalaryAcctEmployeeWrapper getSalaryAcctEmployeeWrapper(User user) {
        return ServiceUtil.getService(SalaryAcctEmployeeWrapper.class, user);
    }

    private ProgressService getSalaryAcctProgressService(User user) {
        return ServiceUtil.getService(ProgressServiceImpl.class, user);
    }

//    private SalaryCheckResultService salaryCheckResultService;


    private SalaryAcctExcelService getSalaryAcctExcelService(User user) {
        return ServiceUtil.getService(SalaryAcctExcelServiceImpl.class, user);
    }

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }

    private SalaryApprovalRuleService getSalaryApprovalRuleService(User user) {
        return ServiceUtil.getService(SalaryApprovalRuleServiceImpl.class, user);
    }

    /**
     * 薪资核算列表
     *
     * @param queryParam 列表查询条件
     * @return
     */
    public Map<String, Object> listPage(SalaryAcctResultQueryParam queryParam) {
        ValidUtil.doValidator(queryParam);
        // 查询薪资核算记录
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId());
        if (Objects.isNull(salaryAcctRecordPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
        }

        // 查询薪资核算结果（分页）
        PageInfo<Map<String, Object>> page = getSalaryAcctResultService(user).listPageByParam(queryParam);

        // 构建薪资核算结果列表的表头
        List<WeaTableColumnGroup> columns = getSalaryAcctExcelService(user).listWeaTableColumn(salaryAcctRecordPO);

        Map<String, Object> datas = new HashMap<>();
        datas.put("pageInfo", page);
        datas.put("columns", columns);

        return datas;
    }

    /**
     * 合计行
     *
     * @param queryParam 列表查询条件
     * @return
     */
    public Map<String, Object> sumSalaryAcctResult(SalaryAcctResultQueryParam queryParam) {
        ValidUtil.doValidator(queryParam);

        Map<String, Object> datas = new HashMap<>();

        //合计
//        SalarySysConfPO openSum = getSalarySysConfService(user).getOneByCode(OPEN_ACCT_RESULT_SUM);
        Map<String, Object> sumRow = getSalaryAcctResultService(user).sumRow(queryParam);
        datas.put("sumRow", sumRow);
        return datas;
    }


    /**
     * 薪资核算列表-报表使用
     *
     * @param queryParam 列表查询条件
     * @return
     */
    @Deprecated
    public Map<String, Object> list(SalaryAcctResultQueryParam queryParam) {
        ValidUtil.doValidator(queryParam);
        // 查询薪资核算记录
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId());
        if (Objects.isNull(salaryAcctRecordPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
        }

        // 查询薪资核算结果
        List<Map<String, Object>> list = getSalaryAcctResultService(user).listByParam(queryParam);

        // 构建薪资核算结果列表的表头
        Map<String, Object> columns = getSalaryAcctExcelService(user).listColumn(salaryAcctRecordPO);

        Map<String, Object> datas = new HashMap<>();
        datas.put("list", list);
        datas.put("columns", columns);

        return datas;
    }

    /**
     * 薪资核算结果详情
     *
     * @param salaryAcctEmployeeId 薪资核算人员id
     * @return
     */
    public SalaryAcctResultDetailDTO getForm(Long salaryAcctEmployeeId) {
        // 获取薪资核算结果详情
        return getSalaryAcctResultService(user).getBySalaryAcctEmployeeId(salaryAcctEmployeeId);
    }

    /**
     * 获取合并计税详情
     *
     * @param salaryAcctEmployeeId 薪资核算人员id
     * @return
     */
    public ConsolidatedTaxDetailDTO getConsolidatedTaxDetail(Long salaryAcctEmployeeId) {
        // 获取合并计税详情
        return getSalaryAcctResultService(user).getConsolidatedTaxDetail(salaryAcctEmployeeId);
    }

    /**
     * 根据薪资核算记录id获取表头数据
     *
     * @param salaryAcctRecordId
     * @return
     */
    public Map<String, SalaryAcctResultListColumnDTO> getColumnBySalaryAcctRecordId(Long salaryAcctRecordId) {
        return getSalaryAcctResultService(user).getColumnBySalaryAcctRecordId(salaryAcctRecordId);
    }

    /**
     * 保存薪资核算结果
     *
     * @param saveParam 保存参数
     */
    public void save(SalaryAcctResultSaveParam saveParam) {
        getSalaryAcctResultService(user).save(saveParam);
    }


    public void lock(SalaryAcctResultLockParam param) {
        getSalaryAcctResultService(user).lock(param);
    }

    /**
     * 更新薪资核算结果的值的锁定状态
     *
     * @param updateParam
     */
    public void updateLockStatusByParam(SalaryAcctResultUpdateLockStatusParam updateParam) {
        getSalaryAcctResultService(user).updateLockStatusByParam(updateParam);
    }

    /**
     * 薪资核算-核算
     *
     * @param calculateParam 薪资核算的参数
     */
    public void calculate(SalaryAcctCalculateParam calculateParam) {
        log.info("开始核算V1{}", calculateParam);


        // 校验是否可以编辑
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(calculateParam.getSalaryAcctRecordId());
        boolean recordIsCanEdit = getSalaryApprovalRuleService(user).getRecordIsCanEdit(salaryAcctRecordPO);
        if (!recordIsCanEdit) {
            throw new SalaryRunTimeException("该核算记录已经发起审批，无法编辑或核算，请先删除审批流程");
        }
        //当前登陆人员
        DataCollectionEmployee simpleEmployee = new DataCollectionEmployee();
        simpleEmployee.setEmployeeId((long) user.getUID());
        // 检查薪资核算人员的个税扣缴义务人
        getSalaryAcctEmployeeWrapper(user).checkTaxAgent(calculateParam.getSalaryAcctRecordId());
        // 检查是否正在核算中
        ProgressDTO salaryAcctProgressDTO = getSalaryAcctProgressService(user).getProgress(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId());
        if (Objects.nonNull(salaryAcctProgressDTO) && salaryAcctProgressDTO.isStatus() && Optional.ofNullable(salaryAcctProgressDTO.getProgress()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ONE) < 0) {
            log.warn("正在核算中，无法再次执行"+calculateParam.getSalaryAcctRecordId());
            return;
        }
        // 初始化进度
        ProgressDTO initProgress = new ProgressDTO()
                .setTitle(SalaryI18nUtil.getI18nLabel(97515, "核算中"))
                .setTitleLabelId(97515L)
                .setTotalQuantity(NumberUtils.INTEGER_ONE)
                .setCalculatedQuantity(NumberUtils.INTEGER_ZERO)
                .setProgress(BigDecimal.ZERO)
                .setStatus(true)
                .setMessage(StringUtils.EMPTY);
        getSalaryAcctProgressService(user).initProgress(SalaryCacheKey.ACCT_PROGRESS + calculateParam.getSalaryAcctRecordId(), initProgress);
        // 异步执行薪资核算
//        LocalRunnable localRunnable = new LocalRunnable() {
//            @Override
//            public void execute() {
//                getSalaryAcctResultService(user).calculate(calculateParam, simpleEmployee);
//            }
//        };
//        ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.HRM, "salaryAcctCalculateV1", localRunnable);
        new Thread() {
            public void run() {
                getSalaryAcctResultService(user).calculate(calculateParam, simpleEmployee);
            }
        }.start();

    }

    /**
     * 检查是否有薪资核算结果的查看权限
     * @param salaryAcctRecordId
     */
    public Boolean checkAuth(Long salaryAcctRecordId) {
//        if(Objects.isNull(salaryAcctRecordId)){
//            return false;
//        }
//        return getSalaryAcctResultService(user).checkAuth(salaryAcctRecordId);
        return true;
    }

    /**
     * 薪资核算结果批量更新
     * @param param
     */
    public void batchUpdate(SalaryAcctResultBatchUpdateParam param) {
        getSalaryAcctResultService(user).batchUpdate(param);
    }

    /**
     * 儿科医院 删除反馈
     * @param param
     */
    public void deleteFeedback(SalaryAcctResultFeedBackParam param) {
        getSalaryAcctResultService(user).deleteFeedback(param);
    }

    public void saveFeedback(SalaryAcctResultFeedBackParam param) {
        getSalaryAcctResultService(user).saveFeedback(param);
    }

    /**
     * 薪资核算-校验
     *
     * @param checkParam     薪资核算的参数
     * @param simpleEmployee 当前登陆人员
     * @param tenantKey      租户key
     */
//    public void check(SalaryAcctCheckParam checkParam, DataCollectionEmployee simpleEmployee, String tenantKey) {
//        // 检查是否正在核算中
//        SalaryAcctProgressDTO salaryAcctProgressDTO = salaryAcctProgressService.getProgress("" + checkParam.getSalaryAcctRecordId(), simpleEmployee.getEmployeeId(), tenantKey);
//        if (Objects.nonNull(salaryAcctProgressDTO) && salaryAcctProgressDTO.isStatus() && Optional.ofNullable(salaryAcctProgressDTO.getProgress()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ONE) < 0) {
//            return;
//        }
//        // 初始化进度
//        SalaryAcctProgressDTO initProgress = new SalaryAcctProgressDTO()
//                .setTitle(SalaryI18nUtil.getI18nLabel(99664, "正在运行校验规则"))
//                .setTitleLabelId(99664L)
//                .setTotalQuantity(NumberUtils.INTEGER_ONE)
//                .setCalculatedQuantity(NumberUtils.INTEGER_ZERO)
//                .setProgress(BigDecimal.ZERO)
//                .setStatus(true)
//                .setMessage(StringUtils.EMPTY);
//        salaryAcctProgressService.initProgress("" + checkParam.getSalaryAcctRecordId(), initProgress, simpleEmployee.getEmployeeId(), tenantKey);
//        // 异步执行校验
//        LocalRunnable localRunnable = new LocalRunnable() {
//            @Override
//            public void execute() {
//                salaryCheckResultService.check(checkParam, false, simpleEmployee, tenantKey);
//            }
//        };
//        ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.OTHER, "salaryAcctCheck", localRunnable);
//    }
}
